package org.zetaframework.core.event;

import cn.hutool.core.util.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.event.EventListener;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
import org.zetaframework.core.helper.EnvHelper;

/**
 * 项目启动监听器
 *
 * @author gcc
 */
@Component
public class StartupListener {

    public static final Logger logger = LoggerFactory.getLogger(StartupListener.class);

    private final EnvHelper envHelper;
    public StartupListener(EnvHelper envHelper) {
        this.envHelper = envHelper;
    }

    /**
     * 项目启动后执行
     */
    @EventListener(ApplicationReadyEvent.class)
    public void onApplicationReady(ApplicationReadyEvent event) {
        // 启动时执行
        ConfigurableApplicationContext context = event.getApplicationContext();
        ConfigurableEnvironment env = context.getEnvironment();
        String applicationName = env.getProperty("spring.application.name");
        String port = env.getProperty("server.port", "8080");
        Boolean swaggerEnabled = env.getProperty("zeta.swagger.enabled", Boolean.class);
        Boolean druidEnabled = env.getProperty("zeta.database.druid.WebConsoleEnabled", Boolean.class);

        // 是否有druid依赖
        boolean hasDruid = isClassPresent("com.alibaba.druid.pool.DruidDataSource");
        // 是否有swagger依赖
        boolean hasSwaggerWebmvc = isClassPresent("org.springdoc.webmvc.ui.SwaggerConfig");
        boolean hasSwaggerWebflux = isClassPresent("org.springdoc.webflux.ui.SwaggerConfig");

        StringBuilder sb = new StringBuilder();
        sb.append("\n----------------------------------------------------------\n");
        sb.append(StrUtil.format("\t项目 '{}' 启动成功!", applicationName));
        // 不是生产环境才打印访问链接
        if (!envHelper.isProdEnvironment()) {
            sb.append(" 访问链接:\n");
        }else {
            sb.append("\n");
        }
        // 如果有swagger依赖，并且swagger文档开关打开，并且不是生产环境
        if ((hasSwaggerWebmvc || hasSwaggerWebflux) && Boolean.TRUE.equals(swaggerEnabled) && !envHelper.isProdEnvironment()) {
            sb.append(StrUtil.format("\tSwagger文档: \t http://127.0.0.1:{}/swagger-ui.html\n", port));

            // 获取openApiUrl。postman、apifox使用
            String openApiUrl = env.getProperty("springdoc.api-docs.path", "/v3/api-docs");
            sb.append(StrUtil.format("\tOpenApi地址: \t http://127.0.0.1:{}{}\n", port, openApiUrl));
        }
        // 如果有druid依赖，并且druid控制台开关打开，并且不是生产环境
        if (hasDruid && Boolean.TRUE.equals(druidEnabled) && !envHelper.isProdEnvironment()) {
            sb.append(StrUtil.format("\t数据库监控: \t\t http://127.0.0.1:{}/druid\n",port));
        }
        sb.append("----------------------------------------------------------");

        logger.info(sb.toString());
    }


    /**
     * 检查类是否存在
     * @param className 类名
     */
    private boolean isClassPresent(String className) {
        return ClassUtils.isPresent(className, getClass().getClassLoader());
    }
}
